package com.zimi.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.zimi.mapper.*;
import com.zimi.model.*;
import com.zimi.util.UserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 组织分类表 Service
 *
 * @author lnintr
 * @since 2019-05-24
 */
@Service
public class SysOrgCateService {
    @Autowired
    private SysOrgCateMapper sysOrgCateMapper;

    @Autowired
    private SysOrgMapper sysOrgMapper;

    @Autowired
    private SysOrgExtendMapper sysOrgExtendMapper;

    @Autowired
    private SysOrgPrivilegeMapper sysOrgPrivilegeMapper;

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private SysPostMapper sysPostMapper;

    @Autowired
    private SysPostPrivilegeMapper sysPostPrivilegeMapper;

    @Autowired
    private SysOrgRoleEmpowerMapper sysOrgRoleEmpowerMapper;

    @Autowired
    private SysRolePrivilegeMapper sysRolePrivilegeMapper;

    /*
     * 取得组织和角色信息
     * */
    public List<SysOrgCate> getList(SysOrgCate sysOrgCate) {
        // 权限控制
        List<SysOrgCate> cateList = sysOrgCateMapper.selectList(new QueryWrapper<SysOrgCate>().lambda().eq(SysOrgCate::getSocState, sysOrgCate.getSocState()).orderByAsc(SysOrgCate::getSocSort));

        return cateList;
    }

    @Transactional
    public Object insert(SysOrgCate sysOrgCate) {
        // 1）确认角色名是否已登录过
        SysOrgCate result = sysOrgCate.selectOne(new QueryWrapper<SysOrgCate>().lambda().eq(SysOrgCate::getSocName, sysOrgCate.getSocName()));
        if (result != null) {
            throw new RuntimeException("分类名为别的机构分类已登录过，请改分类名再提交。");
        }

        SysUser user = UserUtil.getUser();

        sysOrgCate.setSocState(1);
        sysOrgCate.setSocSort(sysOrgCateMapper.selectSort());
        sysOrgCate.setCreateUser(user.getId());
        sysOrgCate.setCreateTime(new Date());

        Object insertResult = sysOrgCate.insert();
        return insertResult;
    }

    @Transactional
    public Object update(SysOrgCate sysOrgCate) {
        // 1）确认角色名是否已登录过
        SysOrgCate result = sysOrgCate.selectOne(new QueryWrapper<SysOrgCate>().lambda().eq(SysOrgCate::getSocName, sysOrgCate.getSocName()));
        if (result != null && result.getId().intValue() != sysOrgCate.getId().intValue()) {
            throw new RuntimeException("分类名为别的机构分类已登录过，请改分类名再提交。");
        }

        // 2）对要修改的对象加行锁
        result = sysOrgCate.selectOne(new QueryWrapper<SysOrgCate>().lambda().eq(SysOrgCate::getId, sysOrgCate.getId()).last("for update"));

        // 3）判断该数据已经被改过没有
        if (result.getUpdateTime() != null) {
            if (sysOrgCate.getUpdateTime() == null) {
                throw new RuntimeException("修改数据失败，数据已经被其他用户改过。");
            } else {
                if (sysOrgCate.getUpdateTime().getTime() != result.getUpdateTime().getTime()) {
                    throw new RuntimeException("删除数据失败，数据已经被其他用户改过。");
                }
            }
        }

        SysUser user = UserUtil.getUser();

        result.setSocName(sysOrgCate.getSocName());
        result.setUpdateUser(user.getId());
        result.setUpdateTime(new Date());

        // 4)变更数据
        return result.updateById();
    }

    @Transactional
    public void delete(SysOrgCate sysOrgCate) {
        // 1）对要修改的对象加行锁
        SysOrgCate result = sysOrgCate.selectOne(new QueryWrapper<SysOrgCate>().lambda().eq(SysOrgCate::getId, sysOrgCate.getId()).last("for update"));

        // 2）判断该数据已经被改过没有
        if (result.getUpdateTime() != null) {
            if (sysOrgCate.getUpdateTime() == null) {
                throw new RuntimeException("删除数据失败，数据已经被其他用户改过。");
            } else {
                if (sysOrgCate.getUpdateTime().getTime() != result.getUpdateTime().getTime()) {
                    throw new RuntimeException("删除数据失败，数据已经被其他用户改过。");
                }
            }
        }

        SysUser user = UserUtil.getUser();
        Date updateTime = new Date();

        // 3)变更数据
        result.setSocState(2);
        result.setUpdateUser(user.getId());
        result.setUpdateTime(updateTime);
        result.updateById();

        // 4）删除机构类型的所属权限
        List<Integer> idList = new ArrayList<>();
        List<SysOrg> orgList = sysOrgMapper.selectList(new QueryWrapper<SysOrg>().lambda().eq(SysOrg::getOrgCate, result.getId()).eq(SysOrg::getOrgState, 1));

        if (orgList != null && orgList.size() > 0) {
            // 5)取得机构的编号一览
            idList.clear();
            for (SysOrg so : orgList) {
                idList.add(so.getId());
            }

            // 6)指定机构下还有人员时
            if (sysOrgExtendMapper.selectUserCountByIds(idList) > 0) {
                throw new RuntimeException("删除数据失败，指定的机构分类下还有用户。");
            }

            // 7）根据编号一览取得机构的权限，岗位，角色
            List<SysOrgPrivilege> privileges = sysOrgPrivilegeMapper.selectList(new QueryWrapper<SysOrgPrivilege>().lambda().in(SysOrgPrivilege::getOrgId, idList).eq(SysOrgPrivilege::getPrivilegeState, 1));
            List<SysPost> sysPosts = sysPostMapper.selectList(new QueryWrapper<SysPost>().lambda().in(SysPost::getOrgId, idList).eq(SysPost::getPostState, 1));
            List<SysOrgRoleEmpower> roleEmpowers = sysOrgRoleEmpowerMapper.selectList(new QueryWrapper<SysOrgRoleEmpower>().lambda().in(SysOrgRoleEmpower::getOrgId, idList).eq(SysOrgRoleEmpower::getSoreState, 1));

            // 8)删除机构
            SysOrg sysOrg = new SysOrg().setUpdateUser(user.getId()).setUpdateTime(updateTime).setOrgState(2);
            sysOrgMapper.update(sysOrg, new UpdateWrapper<SysOrg>().lambda().in(SysOrg::getId, idList));

            // 9)删除机构的权限
            if (privileges != null && privileges.size() > 0) {
                idList.clear();

                for (SysOrgPrivilege sop : privileges) {
                    idList.add(sop.getId());
                }

                // 一次性删除权限
                SysOrgPrivilege sysOrgPrivilege = new SysOrgPrivilege().setUpdateUser(user.getId()).setUpdateTime(updateTime).setPrivilegeState(2);
                sysOrgPrivilegeMapper.update(sysOrgPrivilege, new UpdateWrapper<SysOrgPrivilege>().lambda().in(SysOrgPrivilege::getId, idList));
            }

            // 10)删除机构的岗位和关联权限
            if (sysPosts != null && sysPosts.size() > 0) {
                idList.clear();

                for (SysPost sp : sysPosts) {
                    idList.add(sp.getId());
                }

                // 一次性删除岗位
                SysPost sysPost = new SysPost().setUpdateUser(user.getId()).setUpdateTime(updateTime).setPostState(2);
                sysPostMapper.update(sysPost, new UpdateWrapper<SysPost>().lambda().in(SysPost::getOrgId, idList));

                // 删除对应的岗位权限
                List<SysPostPrivilege> postPrivileges = sysPostPrivilegeMapper.selectList(new QueryWrapper<SysPostPrivilege>().lambda().in(SysPostPrivilege::getPostId, idList).eq(SysPostPrivilege::getPrivilegeState, 1));

                if (postPrivileges != null & postPrivileges.size() > 0) {
                    idList.clear();

                    for (SysPostPrivilege sysPostPrivilege : postPrivileges) {
                        idList.add(sysPostPrivilege.getId());
                    }

                    // 一次性删除岗位权限
                    SysPostPrivilege sysPostPrivilege = new SysPostPrivilege().setUpdateUser(user.getId()).setUpdateTime(updateTime).setPrivilegeState(2);
                    sysPostPrivilegeMapper.update(sysPostPrivilege, new UpdateWrapper<SysPostPrivilege>().lambda().in(SysPostPrivilege::getId, idList));
                }
            }

            // 11)删除机构的角色关联
            if (roleEmpowers != null && roleEmpowers.size() > 0) {
                idList.clear();

                for (SysOrgRoleEmpower sore : roleEmpowers) {
                    idList.add(sore.getId());
                }

                // 一次性删除机构的角色关联
                SysOrgRoleEmpower sysOrgRoleEmpower = new SysOrgRoleEmpower().setUpdateUser(user.getId()).setUpdateTime(updateTime).setSoreState(2);
                sysOrgRoleEmpowerMapper.update(sysOrgRoleEmpower, new UpdateWrapper<SysOrgRoleEmpower>().lambda().in(SysOrgRoleEmpower::getId, idList));
            }
        }
    }

    @Transactional
    public int move(List<SysOrgCate> sysOrgCateList) {
        Map<Integer, SysOrgCate> cateMap = new HashMap<>();
        // 1）对要修改的对象数据数量进行验证
        if (sysOrgCateList.size() != 2) {
            throw new RuntimeException("提交的关于交换顺序的数据不正确。");
        }

        // 2）对要修改的对象加行锁
        List<Integer> idList = new ArrayList<>();
        for (SysOrgCate soc : sysOrgCateList) {
            cateMap.put(soc.getId(), soc);
            idList.add(soc.getId());
        }

        List<SysOrgCate> result = sysOrgCateMapper.selectList(new QueryWrapper<SysOrgCate>().lambda().in(SysOrgCate::getId, idList).last("for update"));

        if (result == null || result.size() != 2) {
            throw new RuntimeException("服务器关于交换顺序的数据异常。");
        }

        SysOrgCate tmpCate = null;

        SysUser user = UserUtil.getUser();
        Date updateTime = new Date();

        for (SysOrgCate soc : result) {
            tmpCate = cateMap.get(soc.getId());

            // 3）判断该数据已经被改过没有
            if (soc.getUpdateTime() != null) {
                if (tmpCate.getUpdateTime() == null) {
                    throw new RuntimeException("删除数据失败，数据已经被其他用户改过。");
                } else {
                    if (soc.getUpdateTime().getTime() != tmpCate.getUpdateTime().getTime()) {
                        throw new RuntimeException("删除数据失败，数据已经被其他用户改过。");
                    }
                }
            }

            // 4)变更数据
            tmpCate.setUpdateUser(user.getId());
            tmpCate.setUpdateTime(updateTime);
            tmpCate.updateById();
        }

        return 0;
    }

    @Transactional
    public int recycle(List<SysOrgCate> sysOrgCateList) {
        Map<Integer, SysOrgCate> cateMap = new HashMap<>();
        // 2）对要修改的对象加行锁
        List<Integer> idList = new ArrayList<>();
        for (SysOrgCate soc : sysOrgCateList) {
            cateMap.put(soc.getId(), soc);
            idList.add(soc.getId());
        }

        List<SysOrgCate> result = sysOrgCateMapper.selectList(new QueryWrapper<SysOrgCate>().lambda().in(SysOrgCate::getId, idList).last("for update"));

        if (result != null && result.size() > 0) {
            SysOrgCate tmpCate = null;

            SysUser user = UserUtil.getUser();
            Date updateTime = new Date();

            for (SysOrgCate soc : result) {
                tmpCate = cateMap.get(soc.getId());

                // 3）判断该数据已经被改过没有
                if (soc.getUpdateTime() != null) {
                    if (tmpCate.getUpdateTime() == null) {
                        throw new RuntimeException("删除数据失败，数据已经被其他用户改过。");
                    } else {
                        if (soc.getUpdateTime().getTime() != tmpCate.getUpdateTime().getTime()) {
                            throw new RuntimeException("删除数据失败，数据已经被其他用户改过。");
                        }
                    }
                }
            }

            SysOrgCate sysOrgCate = new SysOrgCate().setUpdateUser(user.getId()).setUpdateTime(updateTime).setSocState(1);
            sysOrgCateMapper.update(sysOrgCate, new UpdateWrapper<SysOrgCate>().lambda().in(SysOrgCate::getId, idList));
        } else {
            throw new RuntimeException("删除数据失败，数据已经被其他用户改过。");
        }

        return 0;
    }


    /**
     * @author wh
     * @desc 根据分类名查询机构
     */
    public List<SysOrgCate> getDateByName(SysOrgCate cate) {
        List result = sysOrgCateMapper.selectList(new LambdaQueryWrapper<SysOrgCate>().like(SysOrgCate::getSocName, cate.getSocName()));

        return result;
    }

}
